如果你把 ChatGPT 當成 Google 搜尋,你可能會很失望。我問他海狸大師是誰,這是他的回答…
為什麼會這樣?這是因為這個語言模型當初在訓練的時候,就沒有和「海狸大師」有關的訓練資料,所以他出現了「幻覺 (Hallucination)」。(延伸閱讀:錯覺 (illusion)、幻覺(hallucination)、妄想 (delusion)的不同)
幻覺可以大致分成兩種 (範例可以看論文第六頁):
(資料來源:A Survey on Hallucination in Large Language Models: Principles, Taxonomy, Challenges, and Open Questions,這篇論文對幻覺做了更細的分類,有興趣的一定要看一下)
造成幻覺大概可以分為「資料面」、「訓練面」和「推理面」
今天要介紹的 RAG,就是應用上最常見的解決幻覺的方法。
參考下圖,RAG 就是在將 Prompt 送給模型推論之前,先去向量資料庫搜尋資料,把查到的資料當成上下文,送給模型去推論。有點像你想要問一個人「你知道『登鸛雀樓』是什麼嗎?」,在他回答前,先讓他去查資料,所以你問這個人完整的話就會是
請參考以下資料,回答我的問題
"""
《登鸛雀樓》,又名《登鸛鵲樓》,是唐詩五言絕句,一般認為作者是王之渙。 鸛雀樓在今山西永濟市,風景秀麗,歷代騷人墨客多來登樓放歌抒懷,故有大量吟詠之作。沈括認為只有李益、王文奐、暢諸三篇能狀其景。此詩最早見於《國秀集》,作者題為朱斌。
"""
問題:「你知道『登鸛雀樓』是什麼嗎?」
(資料來自維基百科)
完整的流程可以參考下圖
(圖片來源:Retrieval-Augmented Generation for Large Language Models: A Survey)
RAG 主要有三個步驟
其實很像昨天用工具的方法,但不是靠模型去判斷要不要使用工具,而是直接就先用工具搜尋結果,而且這個搜尋方式還不是用字串比對,而是比相似度。
這個步驟又可以細分為
以上,其實和一般的資料庫沒有太大的差別,最大的差別就在多了一個「向量化」步驟。
接下來,我會畫幾張圖的幫助你理解這個流程發生了什麼事
我們會先把資料 / 文本 (Document) 切成一段一段的,這一段一段的東西叫做一個區塊 (chunk)。
以「這隻羊駝喜歡吃蘋果」這句話為例,我們在資料處理的時候可能會加入一些分隔符號 (delimiters),所以可能會變成「這隻羊駝,喜歡,吃,蘋果」
我們把這些東西對應成一個表情符號,方便等等說明
補充說明:在 NLP 領域,「詞 (word)」是最小的能獨立使用的音義結合體,能夠獨立表達語意或與用內容的基本單元。在以英語為代表的印歐語系 (Indo-European languages) 中,詞與詞之間通常會用空白劃分。但在以中文為代表的漢藏語系 (Sino-Tibetan languages),並不包含明顯的分隔符號。因此,為了方便後續的自然語言處理,我們會將沒有明顯分隔符號的語言的句子進行分詞 (Word segmentation) 操作。這邊我舉的例子「這隻羊駝喜歡吃蘋果」更像是「分詞 (word segmentation)」,而不是切塊 (chunk),只是為了方便圖示而這樣寫。切塊通常是針對文章、網頁內容、pdf 檔案等等由多個句子組成多個章節的文本來處理。 (如果我有講錯請幫我補充 ><)
在做向量化之前,我們要先認識什麼是「詞嵌入表示 (Word Embedding)」,詞嵌入是自然語言處理 (NLP) 領域中常用的一種技術的統稱,使用一個連續、低維、稠密的向量來表示詞,經常直接簡稱為詞向量。簡單來說就是把詞這個東東變成數字 (這樣講太簡單了但我也不知道怎麼講比較好)。
「嵌入 (Embedding)」一詞來自數學領域,是指一個數學結構經映射包含到另一個結構中,在這邊就是把詞映射到多維度的向量空間。
向量化就是將資料轉換成數學向量 (數值) 的過程,因為電腦本身無法理解文本資料,但可以處理數字形式的資料。
選擇一個嵌入模型 (Embedded Model),嵌入模型有好多種,不過大部分的嵌入模型都是針對英文去訓練的,請謹慎挑選。ihower 大大有一篇文章〈使用繁體中文評測各家 Embedding 模型的檢索能力〉,你可以參考他的結論來選擇模型。
向量化後的這些區塊,它們就像在座標平面的表情符號們,當然實際上這個東西是難以畫成圖的,不過為了示範方便我們就以二維來示範。
這個東西就是向量資料庫畫成圖可能長成的樣子,我們就姑且把他當向量資料庫吧XD
過去的檢索方式可能是直接搜尋字串,然後做字串比對,像我搜尋「訓練」然後把有關訓練的句子都抓出來
但在向量資料庫中檢索,我們用的是「比距離」的方式,如果你懂一咪咪機器學習應該會聽過 KNN 演算法,就是找到前 K 個最近的鄰居,檢索的步驟也是在做一樣的事
假設我在剛剛建立好的向量資料庫搜尋「蘋果派」,並且設定 top_k
為 2,我在做的事情就是去看看「蘋果派」這個詞會對應到向量資料庫的哪個位置
因為我的 top_k
設定為 2,所以找距離蘋果派最近的兩個東西,會得到「蘋果 Logo」和「紅蘋果」這兩個向量
最後就是將搜尋到的東西當成上下文讓模型去推論,如果我問了「蘋果是什麼顏色?」,RAG 系統會先去找到和「蘋果」最接近的兩個向量,在這邊可能是「蘋果」和「蘋果 Logo」,將他們當成上下文,讓語言模型可以根據現有的參考資料去回答。
恭喜你!從語言模型出現的幻覺,到現在使用 RAG 去解決它,你都有基本概念了,我們明天就用現有的套件 (LlamaIndex) 搭配網路爬蟲來實作一個簡單的 RAG 問答系統吧!
主流的 RAG 會遇到一些問題,因為 RAG 還是依賴文本內容去搜尋,終究無法真正理解文本,我如果問 「總結一下公司的所有技術團隊的研究成果」這種問題,它需要將多個不同的來源整合在一起,目前辦不到;或是「在目前的市場環境,哪些因素影響了我們的營業額?」這種需要知道多種因素之間關係的問題,現有的 RAG 無法解決。說白了 RAG 終究只是高級版的 Ctrl + F。
微軟團隊在七月初發表的 GraphRag 嘗試用知識圖譜來解決這個問題,有興趣的朋友可以研究看看。你也可以參考這篇文章用不同的模型來取代傳統的關鍵字匹配,我覺得蠻有趣的但沒時間試哈哈哈,如果你有心得也可以跟我分享一下 ><。